﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Xml;

namespace DoAn
{
    public class Menu
    {
        KeyboardState lastKbState;
        GamePadState lastGPState;

        List<MenuWindow> mnuList;
        MenuWindow _mnuActive;

        internal MenuWindow mnuActive
        {
            get { return _mnuActive; }
            set { _mnuActive = value; }
        }
        bool _bRunning;

        public bool bRunning
        {
            get { return _bRunning; }
            set { _bRunning = value; }
        }
        bool bNewGame;
        bool _bSound;

        public bool bSound
        {
            get { return _bSound; }
            set { _bSound = value; }
        }

        bool bSnd;

        bool _bPause;
        bool bFlag;
        bool _bQuit;

        bool bHighScrs;


        public bool bQuit
        {
            get { return _bQuit; }
            set { _bQuit = value; }
        }

        public bool bPause
        {
            get { return _bPause; }
            set { _bPause = value; }
        }

        Texture2D textureTextbox;
        String strPlayerName = "";

        public String StrPlayerName
        {
            get { return strPlayerName; }
        }
        SpriteFont font;
        KeyboardState oldKeyboardState;
        KeyboardState currentKeyboardState;

        MenuWindow mnuGameEasy;
        MenuWindow mnuGameNormal;
        MenuWindow mnuGameHard;

        MenuWindow _mnuHighSrs;

        MenuWindow mnuSoundOn;
        MenuWindow mnuSoundOff;

        MenuWindow mnuQuitMsn;

        MenuWindow _mnuNewGame;
        MenuWindow _menuPlaying;
        MenuWindow _mnuOptions;

        internal MenuWindow MenuPlaying
        {
            get { return _menuPlaying; }
            set { _menuPlaying = value; }
        }

        public delegate void LevelHandler();
        public event LevelHandler easy;
        public event LevelHandler normal;
        public event LevelHandler hard;

        public delegate void PlayingHandler();
        public event PlayingHandler quitmsn;

        public delegate void SoundHandler();
        public event SoundHandler onSound;
        public event SoundHandler offSound;

        public Menu()
        {
            mnuList = new List<MenuWindow>();
            _bRunning = true;
            bNewGame = false;
            bHighScrs = false;
            bSound = false;
            bSnd = false;
            _bPause = false;
            bFlag = false;
            _bQuit = false;
            lastKbState = Keyboard.GetState();
            lastGPState = GamePad.GetState(PlayerIndex.One);
        }

        public void LoadContent(ContentManager content)
        {
            SpriteFont spriteFont = content.Load<SpriteFont>("Menus/TheFont");
            Texture2D[] textureBg = new Texture2D[4];
            textureBg[0] = content.Load<Texture2D>("Menus/bg00");
            textureBg[1] = content.Load<Texture2D>("Menus/bg01");
            textureBg[2] = content.Load<Texture2D>("Menus/bg02");
            textureBg[3] = content.Load<Texture2D>("Menus/bgPauses");

            Texture2D textMain = content.Load<Texture2D>("Menus/main00");
            Texture2D textStart = content.Load<Texture2D>("Menus/newgames");
            Texture2D textOption = content.Load<Texture2D>("Menus/option");
            Texture2D textPlaying = content.Load<Texture2D>("Menus/MenuPause");
            Texture2D textHighScrs = content.Load<Texture2D>("Menus/highscore");

            Texture2D textNew = content.Load<Texture2D>("Menus/newgame");
            Texture2D textHigh = content.Load<Texture2D>("Menus/highscores");
            Texture2D textOpt = content.Load<Texture2D>("Menus/options");
            Texture2D textExit = content.Load<Texture2D>("Menus/exit");

            Texture2D textNewS = content.Load<Texture2D>("Menus/newgameSelection");
            Texture2D textHighS = content.Load<Texture2D>("Menus/highscoresSelection");
            Texture2D textOptS = content.Load<Texture2D>("Menus/optionSelection");
            Texture2D textExitS = content.Load<Texture2D>("Menus/exitSelection");

            Texture2D textEasy = content.Load<Texture2D>("Menus/easy");
            Texture2D textNormal = content.Load<Texture2D>("Menus/normal");
            Texture2D textInsane = content.Load<Texture2D>("Menus/insane");
            Texture2D textEasyS = content.Load<Texture2D>("Menus/easySelection");
            Texture2D textNormalS = content.Load<Texture2D>("Menus/normalSelection");
            Texture2D textInsaneS = content.Load<Texture2D>("Menus/insaneSelection");

            Texture2D textQuitMsn = content.Load<Texture2D>("Menus/quitmission");
            Texture2D textQuitMsnS = content.Load<Texture2D>("Menus/quitmissionS");

            Texture2D textResume = content.Load<Texture2D>("Menus/resume");
            Texture2D textResumeS = content.Load<Texture2D>("Menus/resumeS");

            Texture2D textSound = content.Load<Texture2D>("Menus/sound");
            Texture2D textBrightness = content.Load<Texture2D>("Menus/brightness");
            Texture2D textMusic = content.Load<Texture2D>("Menus/bgmusic");
            Texture2D textSoundS = content.Load<Texture2D>("Menus/soundS");
            Texture2D textBrightnessS = content.Load<Texture2D>("Menus/brightnessS");
            Texture2D textMusicS = content.Load<Texture2D>("Menus/bgmusicS");

            Texture2D textSoundMenu = content.Load<Texture2D>("Menus/soundMenu");
            Texture2D textSoundOn = content.Load<Texture2D>("Menus/soundon");
            Texture2D textSoundOnC = content.Load<Texture2D>("Menus/soundonC");
            Texture2D textSoundOff = content.Load<Texture2D>("Menus/soundoff");
            Texture2D textSoundOffC = content.Load<Texture2D>("Menus/soundoffC");

            Texture2D textBack = content.Load<Texture2D>("Menus/back");
            Texture2D textBackSelection = content.Load<Texture2D>("Menus/backSelection");

            textureTextbox = content.Load<Texture2D>("images/others/chat");
            font = content.Load<SpriteFont>("SpriteFont1");

            // Masquerade Menu
            mnuGameEasy = new MenuWindow(null, null, null);
            mnuGameNormal = new MenuWindow(null, null, null);
            mnuGameHard = new MenuWindow(null, null, null);

            mnuQuitMsn = new MenuWindow(null, null, null);

            mnuSoundOn = new MenuWindow(null, null, null);
            mnuSoundOff = new MenuWindow(null, null, null);


            MenuWindow mnuMain = new MenuWindow(spriteFont, textMain, textureBg[0]);
            MenuWindow mnuNewGame = new MenuWindow(spriteFont, textStart, textureBg[1]);
            MenuWindow mnuOptions = new MenuWindow(spriteFont, textOption, textureBg[2]);
            MenuWindow mnuPlaying = new MenuWindow(spriteFont, textPlaying, textureBg[3]);
            MenuWindow mnuHighScore = new MenuWindow(spriteFont, textHighScrs, textureBg[0]);

            MenuWindow mnuSound = new MenuWindow(spriteFont, textSoundMenu, textureBg[0]);

            mnuList.Add(mnuMain);
            mnuList.Add(mnuNewGame);
            mnuList.Add(mnuOptions);
            mnuList.Add(mnuHighScore);
            mnuList.Add(mnuPlaying);
            mnuList.Add(mnuSound);

            mnuMain.AddMenuItem(textNew, textNewS, mnuNewGame);
            mnuMain.AddMenuItem(textHigh, textHighS, mnuHighScore);
            mnuMain.AddMenuItem(textOpt, textOptS, mnuOptions);
            mnuMain.AddMenuItem(textExit, textExitS, null);

            mnuNewGame.AddMenuItem(textEasy, textEasyS, mnuGameEasy);
            mnuNewGame.AddMenuItem(textNormal, textNormalS, mnuGameNormal);
            mnuNewGame.AddMenuItem(textInsane, textInsaneS, mnuGameHard);
            mnuNewGame.AddMenuItem(textBack, textBackSelection, mnuMain);
            _mnuNewGame = mnuNewGame;

            mnuOptions.AddMenuItem(textSound, textSoundS, mnuSound);
            mnuOptions.AddMenuItem(textBrightness, textBrightnessS, mnuMain);
            mnuOptions.AddMenuItem(textMusic, textMusicS, mnuMain);
            mnuOptions.AddMenuItem(textBack, textBackSelection, mnuMain);
            _mnuOptions = mnuOptions;

            mnuHighScore.AddMenuItem(textBack, textBackSelection, mnuMain);
            _mnuHighSrs = mnuHighScore;

            mnuSound.AddMenuItem(textSoundOn, textSoundOnC, mnuSoundOn);
            mnuSound.AddMenuItem(textSoundOff, textSoundOffC, mnuSoundOff);

            mnuPlaying.AddMenuItem(textQuitMsn, textQuitMsnS, mnuQuitMsn);
            mnuPlaying.AddMenuItem(textExit, textExitS, null);
            _menuPlaying = mnuPlaying;

            mnuActive = mnuMain;
            mnuMain.ActiveWindow();
        }

        public void Update(Game1 game, GameTime gameTime)
        {
            GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
            KeyboardState kbState = Keyboard.GetState();

            if (_bRunning || bPause)
            {
                foreach (MenuWindow currMenu in mnuList)
                    currMenu.Update(gameTime.ElapsedGameTime.TotalMilliseconds);

                MenuInput(game, kbState, gamePadState);

                if (bNewGame)
                {
                    //Typing
                    oldKeyboardState = currentKeyboardState;
                    currentKeyboardState = Keyboard.GetState();
                    Keys[] pressedKeys;
                    pressedKeys = currentKeyboardState.GetPressedKeys();

                    foreach (Keys key in pressedKeys)
                    {
                        if (oldKeyboardState.IsKeyUp(key))
                        {
                            if (key == Keys.Back) // overflows
                            {
                                if (strPlayerName.Length > 0)
                                    strPlayerName = strPlayerName.Remove(strPlayerName.Length - 1, 1);
                            }
                            else
                                if (key == Keys.Space)
                                    strPlayerName = strPlayerName.Insert(strPlayerName.Length, " ");
                                else
                                {
                                    switch (key)
                                    {
                                        case Keys.D0: strPlayerName += (0).ToString(); break;
                                        case Keys.D1: strPlayerName += (1).ToString(); break;
                                        case Keys.D2: strPlayerName += (2).ToString(); break;
                                        case Keys.D3: strPlayerName += (3).ToString(); break;
                                        case Keys.D4: strPlayerName += (4).ToString(); break;
                                        case Keys.D5: strPlayerName += (5).ToString(); break;
                                        case Keys.D6: strPlayerName += (6).ToString(); break;
                                        case Keys.D7: strPlayerName += (7).ToString(); break;
                                        case Keys.D8: strPlayerName += (8).ToString(); break;
                                        case Keys.D9: strPlayerName += (9).ToString(); break;
                                        default:
                                            {
                                                if (strPlayerName.ToLower().Contains("up"))
                                                    strPlayerName = strPlayerName.Remove(strPlayerName.Length - 2, 2);
                                                if (strPlayerName.ToLower().Contains("down"))
                                                    strPlayerName = strPlayerName.Remove(strPlayerName.Length - 4, 4);
                                                if (strPlayerName.ToLower().Contains("right"))
                                                    strPlayerName = strPlayerName.Remove(strPlayerName.Length - 5, 5);
                                                if (strPlayerName.ToLower().Contains("left"))
                                                    strPlayerName = strPlayerName.Remove(strPlayerName.Length - 4, 4);
                                                if (strPlayerName.ToLower().Contains("enter"))
                                                    strPlayerName = strPlayerName.Remove(strPlayerName.Length - 5, 5);

                                                strPlayerName += key.ToString();
                                            }
                                            break;
                                    }
                                }
                        }
                    }
                }
            }

            if (bSound)
            {
                foreach (MenuWindow currMenu in mnuList)
                    currMenu.Update(gameTime.ElapsedGameTime.TotalMilliseconds);
                MenuInput(game, kbState, gamePadState);
                bSound = false;
                _bRunning = true;
            }

            if (bQuit)
            {
                foreach (MenuWindow currMenu in mnuList)
                    currMenu.Update(gameTime.ElapsedGameTime.TotalMilliseconds);
                MenuInput(game, kbState, gamePadState);
                bQuit = false;
                _bRunning = true;
            }


            lastKbState = kbState;
            lastGPState = gamePadState;
        }

        public void Draw(GameTime gameTime, GraphicsDevice device, SpriteBatch spriteBatch)
        {
            device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Transparent, 1, 0);

            if (_bRunning || bPause)
            {
                foreach (MenuWindow currMenu in mnuList)
                    currMenu.Draw(spriteBatch);
                if (bNewGame)
                {
                    //Hien thi textbox
                    spriteBatch.Draw(textureTextbox, new Rectangle(250, 200, 300, 25), Color.White);
                    if (strPlayerName.ToLower().Contains("up"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 2, 2);
                    if (strPlayerName.ToLower().Contains("down"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 4, 4);
                    if (strPlayerName.ToLower().Contains("right"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 5, 5);
                    if (strPlayerName.ToLower().Contains("left"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 4, 4);
                    if (strPlayerName.ToLower().Contains("enter"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 5, 5);
                    spriteBatch.DrawString(font, strPlayerName.ToLower(), new Vector2(250, 200), Color.Red);
                }

                if (bHighScrs)
                {
                    spriteBatch.Draw(textureTextbox, new Rectangle(550, 200, 300, 400), Color.White);
                    string strHighScores = "";
                    XmlTextReader xmlTextReader = new XmlTextReader("highscore00.xml");
                    while(xmlTextReader.Read())
                    {
                        if (xmlTextReader.Name == "USER")
                        {
                            strHighScores += xmlTextReader.GetAttribute("Name") + "===>" + xmlTextReader.GetAttribute("Score");
                            strHighScores += "\n_________________\n";
                        }
                    }
                    spriteBatch.DrawString(font, "==> HIGHT SCORES <==\n Name    Score\n=======o0o=======\n" + strHighScores, new Vector2(550, 200), Color.Red);
                }
            }
            if (bQuit)
            {
                foreach (MenuWindow currMenu in mnuList)
                    currMenu.Draw(spriteBatch);
                if (bNewGame)
                {
                    //Hien thi textbox
                    spriteBatch.Draw(textureTextbox, new Rectangle(250, 200, 300, 25), Color.White);
                    if (strPlayerName.ToLower().Contains("up"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 2, 2);
                    if (strPlayerName.ToLower().Contains("down"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 4, 4);
                    if (strPlayerName.ToLower().Contains("right"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 5, 5);
                    if (strPlayerName.ToLower().Contains("left"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 4, 4);
                    if (strPlayerName.ToLower().Contains("enter"))
                        strPlayerName = strPlayerName.Remove(strPlayerName.Length - 5, 5);
                    spriteBatch.DrawString(font, strPlayerName.ToLower(), new Vector2(250, 200), Color.Red);
                }
            }

            else if (bSound)
            {
                foreach (MenuWindow currMenu in mnuList)
                    currMenu.Draw(spriteBatch);
            }

            else
            {
                device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Red, 1, 0);
            }
        }

        private void MenuInput(Game1 game, KeyboardState currKbState,
            GamePadState currGPState)
        {
            if (mnuActive != null)
            {
                MenuWindow mnuChoice = mnuActive.ProcessInput(lastKbState,
                    currKbState, lastGPState, currGPState);
                if (bPause && !bFlag)
                {
                    mnuChoice = MenuPlaying;
                    bFlag = true;
                }

                if (mnuChoice == _mnuHighSrs)
                {
                    bHighScrs = true;
                }

                if (mnuChoice != _mnuHighSrs)
                {
                    if (bHighScrs)
                        bHighScrs = false;
                }

                if (mnuChoice == _mnuNewGame)
                {
                    bNewGame = true;
                }

                if (mnuChoice != _mnuNewGame &&
                    (mnuChoice != mnuGameEasy && mnuChoice != mnuGameNormal && mnuChoice != mnuGameHard))
                {
                    bNewGame = false;
                    strPlayerName = "";
                }

                if (mnuChoice == mnuGameEasy)
                {
                    _bRunning = false;
                    easy();
                }
                else if (mnuChoice == mnuGameNormal)
                {
                    _bRunning = false;
                    normal();
                }
                else if (mnuChoice == mnuGameHard)
                {
                    _bRunning = false;
                    hard();
                }

                else if (mnuChoice == mnuQuitMsn)
                {
                    bQuit = true;
                    _bRunning = false;
                    mnuChoice = _mnuHighSrs;
                    quitmsn();
                }
                else if (mnuChoice == mnuSoundOn)
                {
                    bSound = true;
                    _bRunning = false;
                    mnuChoice = _mnuOptions;
                    onSound();
                }
                else if (mnuChoice == mnuSoundOff)
                {
                    bSound = true;
                    _bRunning = false;
                    mnuChoice = _mnuOptions;
                    offSound();
                }
                else if (mnuChoice == null)
                    game.Exit();

                else if (mnuChoice != mnuActive)
                {
                    if (bSound && !bSnd)
                    {
                        bSnd = true;
                        mnuChoice = _mnuOptions;
                    }

                    if (bQuit)
                        mnuChoice = _mnuNewGame;
                    mnuChoice.ActiveWindow();
                }
                mnuActive = mnuChoice;
            }
        }
    }
}